# 练习作用域之间的转换
# 全局变量
a = 1

def foo():
    global a
    a = 2
    print(a)

foo()
print(a)


# Enclosed(嵌套)自由变量
def make_averager():
    total = 0
    count = 0
    def averager(value):
        nonlocal total, count
        total += value
        count += 1
        return total / count
    return averager

my_avg = make_averager()
print(my_avg(1))
print(my_avg(2))


# local 局部变量
a = 1
b = []

def foo():
    a = 2
    b.append(2)
    return None
foo()
print(a)
print(b)

# 默写一个装饰器, 用来输出函数的执行时间.
import time
def clock_it_deco(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} execute time: {format(end_time - start_time, '.2f')} s")
        return result
    return wrapper


@clock_it_deco
def foo(a, b):
    count = 1
    while True:
        if count > a ** b:
            break
        count += 1
foo(10, 5)


# 使用装饰器来为斐波那契函数添加缓存
def cache_deco(func):
# 保存n执行后的结果
    a = {1: 1, 2: 1, 3: 2, 4: 3, 5: 5, 6: 8}
# 判断当前cache a中是否有结果, 有的话就直接返回, 没有就执行以下
    def wrapper(*args):
        if args not in a:
            a[args] = func(*args)
        return a[args]
    return wrapper


@cache_deco
def fact(n):
    if n <= 1:
        return n
    return fact(n-2) + fact(n-1)


print(fact(6))
